package pl.wwysocki.gendok;

import java.lang.reflect.Method;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.odftoolkit.odfdom.doc.text.OdfTextParagraph;
import org.odftoolkit.odfdom.doc.text.OdfTextUserFieldGet;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

public class FieldRef
{
	public static final String ODF_TEXT_NS = "urn:oasis:names:tc:opendocument:xmlns:text:1.0";
	private static final Log log = LogFactory.getLog(FieldRef.class);
	private String name;
	private Method getter;
	private Node tableDef;
	private Node tableRow;
	private Node cell;
	private Node paragraph;
	private Node element;

	public FieldRef()
	{
		super();
	}

	public FieldRef(String name, Node element, Method getter)
	{
		super();
		this.name = name;
		this.getter = getter;
		this.paragraph = element.getParentNode();
		this.cell = paragraph.getParentNode();
		this.tableRow = cell.getParentNode();
		this.tableDef = tableRow.getParentNode();
		if (!(paragraph instanceof OdfTextParagraph))
		{
			log.error(String.format("Blad - pole %s jest umieszczone wewnątrz %s zamiast w paragrafie.", name,
					paragraph.getNodeName()));
		}
		this.element = element;
	}

	public void generateTables(Object obj)
	{
		Object value = null;
		try
		{
			if (getter != null && obj != null)
			{
				value = getter.invoke(obj, null);
			}
			else
			{
				log.error(String.format("Brak gettera %s lub obiektu %s.", getter.getName(), obj.toString()));
			}
		}
		catch (Exception e)
		{
			log.error(String.format("Blad wywolania metody %s na rzecz obiektu %s", getter.getName(), obj.toString()));
			e.printStackTrace();
		}
		if (value != null)
		{
			try
			{
				String strValue = value.toString();
				if (value instanceof Boolean)
				{
					strValue = ((Boolean) value) ? "tak" : "nie";
				}
				if (strValue == null)
					strValue = "";
				String[] rows = strValue.split("\n");
				Document doc = paragraph.getOwnerDocument();
				Node node = null;
				if (rows.length > 1)
				{
					try 
					{
						while (cell.getFirstChild() != null)
							cell.removeChild(cell.getFirstChild());
					}
					catch (Throwable t)
					{
						log.error(t.getMessage());
					}
					for (String row : rows)
					{
						Element p = doc.createElementNS(ODF_TEXT_NS, "text:p");
						p.setAttributeNS(ODF_TEXT_NS, "text:style-name", "Table_20_Contents");
						p.setTextContent(row);
						cell.appendChild(p);
						element = cell;
					}
				}
				else
				{
					node = paragraph.getOwnerDocument().createTextNode(strValue);
					paragraph.replaceChild(node, element);
					element = node;
				}
			}
			catch (Throwable t)
			{
				log.error(String.format("Blad %s z wstawieniem wartosci pola %s: %s", t.getMessage(), name, element.getLocalName()));
				t.printStackTrace();
			}
		}
	}

	public String getName()
	{
		return name;
	}

	public void setName(String name)
	{
		this.name = name;
	}

	public Object getIdentifier()
	{
		return this;
	}

	public Method getGetter()
	{
		return getter;
	}

	public void setGetter(Method getter)
	{
		this.getter = getter;
	}

	public Node getTableDef()
	{
		return tableDef;
	}

	public void setTableDef(Node tableDef)
	{
		this.tableDef = tableDef;
	}

	public Node getTableRow()
	{
		return tableRow;
	}

	public void setTableRow(Node tableRow)
	{
		this.tableRow = tableRow;
	}

	public Node getParagraph()
	{
		return paragraph;
	}

	public void setParagraph(Node paragraph)
	{
		this.paragraph = paragraph;
	}

	public void show()
	{
		log.info("FieldRef");
		log.info(String.format("nazwa: %s", name));
		log.info(String.format("getter: %s", getter.getName()));
		log.info("------------------------");
	}

	public void removeTableRow()
	{
	}

	public void resetTable()
	{
	}

	public void parse(OdfTextUserFieldGet element2, String attrName, Object bean1)
	{
		// TODO Auto-generated method stub
		
	}
}
